﻿/*
 * zdomain.cxx
 *
 *  Created on: 2015年4月3日
 *      Author: Fifi Lyu
 */

#include "zpsoe/zalgorithm/zdomain.h"
#include "zpsoe/zalgorithm/zstring.h"
#include <vector>

using std::vector;
using namespace zpsoe::zalgorithm::zstring;

namespace zpsoe {

namespace zalgorithm {

namespace zdomain {

// 判断域名块是否是有字母、数字以及不在首尾的连字符(中横线)组成  比如abc.com中的abc
ZPSOE_SHARED_LIB_API bool is_domain_block(const string &domain_block) {
    if (domain_block.empty())
        return false;

    // 首尾字符为中横线
    if (domain_block[0] == '-'
            || domain_block[domain_block.size() - 1] == '-')
        return false;

    // 判断是否是有字母、数字以及连字符(中横线)组成
    for (size_t i = 0; i < domain_block.size(); i++) {
        char tmp = domain_block[i];

        if (!isalnum(tmp) && tmp != '-')
            return false;
    }

    return true;
}

ZPSOE_SHARED_LIB_API bool is_domain(const string &domain) {
    const size_t MAX_SIZE_(80);

    if (domain.empty()  // 空
            || domain.size() > MAX_SIZE_  // 长度超过80
                || !zstring::find(domain, ".")  // 没有包含点
                    || zstring::find(domain, "..")) // 包含连续的多个点
        return false;

    vector<string> domain_block_list;
    vector<string>::iterator it;
    zstring::to_vector(domain, domain_block_list, ".");

    // 标准域名至少是abc.com这样，包含两个域名块
    if (domain_block_list.size() < 2)
        return false;

    // *.abc.com泛域名，包含至少3个域名块，以星号开头，则移除星号
    if (domain_block_list.size() >= 3 && domain_block_list.front() == "*")
        domain_block_list.erase(domain_block_list.begin());

    // 英文地理顶级域名，域名最后部分，只能由字母组成
    // 中文域名，域名最后部分，由字母、数字以及中横线组成，
    // 比如xn--zfr9ax31bh2evqaq74ajw1bsu0b.xn--fiqs8s
    string geographic_top_level_domain(domain_block_list.back());

    // 移除数组中，最后一个
    domain_block_list.pop_back();
    if (!is_domain_block(geographic_top_level_domain))
        return false;


    //  除域名最后的国家代码以外
    for (it = domain_block_list.begin();
            it != domain_block_list.end(); it++) {
        if (!is_domain_block(*it))
            return false;
    }

    return true;
}

} /* namespace zdomain */

} /* namespace zalgorithm */

} /* namespace zpsoe */
